4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give.
11 ******************************************************************************
13 ** This SQLite extension implements functions tointeger(X) and toreal(X).
15 ** If X is an integer, real, or string value that can be
16 ** losslessly represented as an integer, then tointeger(X)
17 ** returns the corresponding integer value.
18 ** If X is an 8-byte BLOB then that blob is interpreted as
19 ** a signed two-compliment little-endian encoding of an integer
20 ** and tointeger(X) returns the corresponding integer value.
21 ** Otherwise tointeger(X) return NULL.
23 ** If X is an integer, real, or string value that can be
24 ** convert into a real number, preserving at least 15 digits
25 ** of precision, then toreal(X) returns the corresponding real value.
26 ** If X is an 8-byte BLOB then that blob is interpreted as
27 ** a 64-bit IEEE754 big-endian floating point value
28 ** and toreal(X) returns the corresponding real value.
29 ** Otherwise toreal(X) return NULL.
31 ** Note that tointeger(X) of an 8-byte BLOB assumes a little-endian
32 ** encoding whereas toreal(X) of an 8-byte BLOB assumes a big-endian
35 #include "sqlite3ext.h"
36 SQLITE_EXTENSION_INIT1
41 ** Determine if this is running on a big-endian or little-endian
44 #if defined(i386) || defined(__i386__) || defined(_M_IX86)\
45 || defined(__x86_64) || defined(__x86_64__)
46 # define TOTYPE_BIGENDIAN 0
47 # define TOTYPE_LITTLEENDIAN 1
49 const int totype_one
= 1;
50 # define TOTYPE_BIGENDIAN (*(char *)(&totype_one)==0)
51 # define TOTYPE_LITTLEENDIAN (*(char *)(&totype_one)==1)
55 ** Constants for the largest and smallest possible 64-bit signed integers.
56 ** These macros are designed to work correctly on both 32-bit and 64-bit
60 # define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
63 #ifndef SMALLEST_INT64
64 # define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
68 ** Return TRUE if character c is a whitespace character
70 static int totypeIsspace(unsigned char c
){
71 return c
==' ' || c
=='\t' || c
=='\n' || c
=='\v' || c
=='\f' || c
=='\r';
75 ** Return TRUE if character c is a digit
77 static int totypeIsdigit(unsigned char c
){
78 return c
>='0' && c
<='9';
82 ** Compare the 19-character string zNum against the text representation
83 ** value 2^63: 9223372036854775808. Return negative, zero, or positive
84 ** if zNum is less than, equal to, or greater than the string.
85 ** Note that zNum must contain exactly 19 characters.
87 ** Unlike memcmp() this routine is guaranteed to return the difference
88 ** in the values of the last digit if the only difference is in the
89 ** last digit. So, for example,
91 ** totypeCompare2pow63("9223372036854775800")
95 static int totypeCompare2pow63(const char *zNum
){
98 /* 012345678901234567 */
99 const char *pow63
= "922337203685477580";
100 for(i
=0; c
==0 && i
<18; i
++){
101 c
= (zNum
[i
]-pow63
[i
])*10;
110 ** Convert zNum to a 64-bit signed integer.
112 ** If the zNum value is representable as a 64-bit twos-complement
113 ** integer, then write that value into *pNum and return 0.
115 ** If zNum is exactly 9223372036854665808, return 2. This special
116 ** case is broken out because while 9223372036854665808 cannot be a
117 ** signed 64-bit integer, its negative -9223372036854665808 can be.
119 ** If zNum is too big for a 64-bit integer and is not
120 ** 9223372036854665808 or if zNum contains any non-numeric text,
123 ** The string is not necessarily zero-terminated.
125 static int totypeAtoi64(const char *zNum
, sqlite3_int64
*pNum
, int length
){
126 sqlite3_uint64 u
= 0;
127 int neg
= 0; /* assume positive */
132 const char *zEnd
= zNum
+ length
;
134 while( zNum
<zEnd
&& totypeIsspace(*zNum
) ) zNum
++;
139 }else if( *zNum
=='+' ){
144 while( zNum
<zEnd
&& zNum
[0]=='0' ){ zNum
++; } /* Skip leading zeros. */
145 for(i
=0; &zNum
[i
]<zEnd
&& (c
=zNum
[i
])>='0' && c
<='9'; i
++){
148 if( u
>LARGEST_INT64
){
149 *pNum
= SMALLEST_INT64
;
151 *pNum
= -(sqlite3_int64
)u
;
153 *pNum
= (sqlite3_int64
)u
;
155 if( (c
!=0 && &zNum
[i
]<zEnd
) || (i
==0 && zStart
==zNum
) || i
>19 || nonNum
){
156 /* zNum is empty or contains non-numeric text or is longer
157 ** than 19 digits (thus guaranteeing that it is too large) */
160 /* Less than 19 digits, so we know that it fits in 64 bits */
161 assert( u
<=LARGEST_INT64
);
164 /* zNum is a 19-digit numbers. Compare it against 9223372036854775808. */
165 c
= totypeCompare2pow63(zNum
);
167 /* zNum is less than 9223372036854775808 so it fits */
168 assert( u
<=LARGEST_INT64
);
171 /* zNum is greater than 9223372036854775808 so it overflows */
174 /* zNum is exactly 9223372036854775808. Fits if negative. The
175 ** special case 2 overflow if positive */
176 assert( u
-1==LARGEST_INT64
);
177 assert( (*pNum
)==SMALLEST_INT64
);
184 ** The string z[] is an text representation of a real number.
185 ** Convert this string to a double and write it into *pResult.
187 ** The string is not necessarily zero-terminated.
189 ** Return TRUE if the result is a valid real number (or integer) and FALSE
190 ** if the string is empty or contains extraneous text. Valid numbers
191 ** are in one of these formats:
193 ** [+-]digits[E[+-]digits]
194 ** [+-]digits.[digits][E[+-]digits]
195 ** [+-].digits[E[+-]digits]
197 ** Leading and trailing whitespace is ignored for the purpose of determining
200 ** If some prefix of the input string is a valid number, this routine
201 ** returns FALSE but it still converts the prefix and writes the result
204 static int totypeAtoF(const char *z
, double *pResult
, int length
){
205 const char *zEnd
= z
+ length
;
206 /* sign * significand * (10 ^ (esign * exponent)) */
207 int sign
= 1; /* sign of significand */
208 sqlite3_int64 s
= 0; /* significand */
209 int d
= 0; /* adjust exponent for shifting decimal point */
210 int esign
= 1; /* sign of exponent */
211 int e
= 0; /* exponent */
212 int eValid
= 1; /* True exponent is either not used or is well-formed */
217 *pResult
= 0.0; /* Default return value, in case of an error */
219 /* skip leading spaces */
220 while( z
<zEnd
&& totypeIsspace(*z
) ) z
++;
221 if( z
>=zEnd
) return 0;
223 /* get sign of significand */
231 /* skip leading zeroes */
232 while( z
<zEnd
&& z
[0]=='0' ) z
++, nDigits
++;
234 /* copy max significant digits to significand */
235 while( z
<zEnd
&& totypeIsdigit(*z
) && s
<((LARGEST_INT64
-9)/10) ){
236 s
= s
*10 + (*z
- '0');
240 /* skip non-significant significand digits
241 ** (increase exponent by d to shift decimal left) */
242 while( z
<zEnd
&& totypeIsdigit(*z
) ) z
++, nDigits
++, d
++;
243 if( z
>=zEnd
) goto totype_atof_calc
;
245 /* if decimal point is present */
248 /* copy digits from after decimal to significand
249 ** (decrease exponent by d to shift decimal right) */
250 while( z
<zEnd
&& totypeIsdigit(*z
) && s
<((LARGEST_INT64
-9)/10) ){
251 s
= s
*10 + (*z
- '0');
254 /* skip non-significant digits */
255 while( z
<zEnd
&& totypeIsdigit(*z
) ) z
++, nDigits
++;
257 if( z
>=zEnd
) goto totype_atof_calc
;
259 /* if exponent is present */
260 if( *z
=='e' || *z
=='E' ){
263 if( z
>=zEnd
) goto totype_atof_calc
;
264 /* get sign of exponent */
271 /* copy digits to exponent */
272 while( z
<zEnd
&& totypeIsdigit(*z
) ){
273 e
= e
<10000 ? (e
*10 + (*z
- '0')) : 10000;
279 /* skip trailing spaces */
280 if( nDigits
&& eValid
){
281 while( z
<zEnd
&& totypeIsspace(*z
) ) z
++;
285 /* adjust exponent by d, and update sign */
294 /* if 0 significand */
296 /* In the IEEE 754 standard, zero is signed.
297 ** Add the sign if we've seen at least one digit */
298 result
= (sign
<0 && nDigits
) ? -(double)0 : (double)0;
300 /* attempt to reduce exponent */
302 while( s
<(LARGEST_INT64
/10) && e
>0 ) e
--,s
*=10;
304 while( !(s
%10) && e
>0 ) e
--,s
/=10;
307 /* adjust the sign of significand */
310 /* if exponent, scale significand as appropriate
311 ** and store in result. */
314 /* attempt to handle extremely small/large numbers better */
315 if( e
>307 && e
<342 ){
316 while( e
%308 ) { scale
*= 1.0e+1; e
-= 1; }
328 result
= 1e308
*1e308
*s
; /* Infinity */
331 /* 1.0e+22 is the largest power of 10 than can be
332 ** represented exactly. */
333 while( e
%22 ) { scale
*= 1.0e+1; e
-= 1; }
334 while( e
>0 ) { scale
*= 1.0e+22; e
-= 22; }
346 /* store the result */
349 /* return true if number and no extra non-whitespace chracters after */
350 return z
>=zEnd
&& nDigits
>0 && eValid
&& nonNum
==0;
354 ** tointeger(X): If X is any value (integer, double, blob, or string) that
355 ** can be losslessly converted into an integer, then make the conversion and
356 ** return the result. Otherwise, return NULL.
358 static void tointegerFunc(
359 sqlite3_context
*context
,
365 switch( sqlite3_value_type(argv
[0]) ){
367 double rVal
= sqlite3_value_double(argv
[0]);
368 sqlite3_int64 iVal
= (sqlite3_int64
)rVal
;
369 if( rVal
==(double)iVal
){
370 sqlite3_result_int64(context
, iVal
);
374 case SQLITE_INTEGER
: {
375 sqlite3_result_int64(context
, sqlite3_value_int64(argv
[0]));
379 const unsigned char *zBlob
= sqlite3_value_blob(argv
[0]);
381 int nBlob
= sqlite3_value_bytes(argv
[0]);
382 if( nBlob
==sizeof(sqlite3_int64
) ){
384 if( TOTYPE_BIGENDIAN
){
386 unsigned char zBlobRev
[sizeof(sqlite3_int64
)];
387 for(i
=0; i
<sizeof(sqlite3_int64
); i
++){
388 zBlobRev
[i
] = zBlob
[sizeof(sqlite3_int64
)-1-i
];
390 memcpy(&iVal
, zBlobRev
, sizeof(sqlite3_int64
));
392 memcpy(&iVal
, zBlob
, sizeof(sqlite3_int64
));
394 sqlite3_result_int64(context
, iVal
);
400 const unsigned char *zStr
= sqlite3_value_text(argv
[0]);
402 int nStr
= sqlite3_value_bytes(argv
[0]);
403 if( nStr
&& !totypeIsspace(zStr
[0]) ){
405 if( !totypeAtoi64((const char*)zStr
, &iVal
, nStr
) ){
406 sqlite3_result_int64(context
, iVal
);
413 assert( sqlite3_value_type(argv
[0])==SQLITE_NULL
);
420 ** toreal(X): If X is any value (integer, double, blob, or string) that can
421 ** be losslessly converted into a real number, then do so and return that
422 ** real number. Otherwise return NULL.
424 #if defined(_MSC_VER)
425 #pragma warning(disable: 4748)
426 #pragma optimize("", off)
428 static void torealFunc(
429 sqlite3_context
*context
,
435 switch( sqlite3_value_type(argv
[0]) ){
437 sqlite3_result_double(context
, sqlite3_value_double(argv
[0]));
440 case SQLITE_INTEGER
: {
441 sqlite3_int64 iVal
= sqlite3_value_int64(argv
[0]);
442 double rVal
= (double)iVal
;
443 if( iVal
==(sqlite3_int64
)rVal
){
444 sqlite3_result_double(context
, rVal
);
449 const unsigned char *zBlob
= sqlite3_value_blob(argv
[0]);
451 int nBlob
= sqlite3_value_bytes(argv
[0]);
452 if( nBlob
==sizeof(double) ){
454 if( TOTYPE_LITTLEENDIAN
){
456 unsigned char zBlobRev
[sizeof(double)];
457 for(i
=0; i
<sizeof(double); i
++){
458 zBlobRev
[i
] = zBlob
[sizeof(double)-1-i
];
460 memcpy(&rVal
, zBlobRev
, sizeof(double));
462 memcpy(&rVal
, zBlob
, sizeof(double));
464 sqlite3_result_double(context
, rVal
);
470 const unsigned char *zStr
= sqlite3_value_text(argv
[0]);
472 int nStr
= sqlite3_value_bytes(argv
[0]);
473 if( nStr
&& !totypeIsspace(zStr
[0]) && !totypeIsspace(zStr
[nStr
-1]) ){
475 if( totypeAtoF((const char*)zStr
, &rVal
, nStr
) ){
476 sqlite3_result_double(context
, rVal
);
484 assert( sqlite3_value_type(argv
[0])==SQLITE_NULL
);
489 #if defined(_MSC_VER)
490 #pragma optimize("", on)
491 #pragma warning(default: 4748)
495 __declspec(dllexport
)
497 int sqlite3_totype_init(
500 const sqlite3_api_routines
*pApi
503 SQLITE_EXTENSION_INIT2(pApi
);
504 (void)pzErrMsg
; /* Unused parameter */
505 rc
= sqlite3_create_function(db
, "tointeger", 1, SQLITE_UTF8
, 0,
506 tointegerFunc
, 0, 0);
508 rc
= sqlite3_create_function(db
, "toreal", 1, SQLITE_UTF8
, 0,