15f8cdac6Sdrh /*
25f8cdac6Sdrh ** 2013-10-14
35f8cdac6Sdrh **
45f8cdac6Sdrh ** The author disclaims copyright to this source code. In place of
55f8cdac6Sdrh ** a legal notice, here is a blessing:
65f8cdac6Sdrh **
75f8cdac6Sdrh ** May you do good and not evil.
85f8cdac6Sdrh ** May you find forgiveness for yourself and forgive others.
95f8cdac6Sdrh ** May you share freely, never taking more than you give.
105f8cdac6Sdrh **
115f8cdac6Sdrh ******************************************************************************
125f8cdac6Sdrh **
135f8cdac6Sdrh ** This SQLite extension implements functions tointeger(X) and toreal(X).
145f8cdac6Sdrh **
155f8cdac6Sdrh ** If X is an integer, real, or string value that can be
165f8cdac6Sdrh ** losslessly represented as an integer, then tointeger(X)
175f8cdac6Sdrh ** returns the corresponding integer value.
185f8cdac6Sdrh ** If X is an 8-byte BLOB then that blob is interpreted as
195f8cdac6Sdrh ** a signed two-compliment little-endian encoding of an integer
205f8cdac6Sdrh ** and tointeger(X) returns the corresponding integer value.
215f8cdac6Sdrh ** Otherwise tointeger(X) return NULL.
225f8cdac6Sdrh **
235f8cdac6Sdrh ** If X is an integer, real, or string value that can be
245f8cdac6Sdrh ** convert into a real number, preserving at least 15 digits
255f8cdac6Sdrh ** of precision, then toreal(X) returns the corresponding real value.
265f8cdac6Sdrh ** If X is an 8-byte BLOB then that blob is interpreted as
275f8cdac6Sdrh ** a 64-bit IEEE754 big-endian floating point value
285f8cdac6Sdrh ** and toreal(X) returns the corresponding real value.
295f8cdac6Sdrh ** Otherwise toreal(X) return NULL.
305f8cdac6Sdrh **
315f8cdac6Sdrh ** Note that tointeger(X) of an 8-byte BLOB assumes a little-endian
325f8cdac6Sdrh ** encoding whereas toreal(X) of an 8-byte BLOB assumes a big-endian
335f8cdac6Sdrh ** encoding.
345f8cdac6Sdrh */
355f8cdac6Sdrh #include "sqlite3ext.h"
365f8cdac6Sdrh SQLITE_EXTENSION_INIT1
375f8cdac6Sdrh #include <assert.h>
385f8cdac6Sdrh #include <string.h>
395f8cdac6Sdrh
405f8cdac6Sdrh /*
415f8cdac6Sdrh ** Determine if this is running on a big-endian or little-endian
425f8cdac6Sdrh ** processor
435f8cdac6Sdrh */
445f8cdac6Sdrh #if defined(i386) || defined(__i386__) || defined(_M_IX86)\
455f8cdac6Sdrh || defined(__x86_64) || defined(__x86_64__)
460593516fSmistachkin # define TOTYPE_BIGENDIAN 0
470593516fSmistachkin # define TOTYPE_LITTLEENDIAN 1
485f8cdac6Sdrh #else
495f8cdac6Sdrh const int totype_one = 1;
500593516fSmistachkin # define TOTYPE_BIGENDIAN (*(char *)(&totype_one)==0)
510593516fSmistachkin # define TOTYPE_LITTLEENDIAN (*(char *)(&totype_one)==1)
525f8cdac6Sdrh #endif
535f8cdac6Sdrh
545f8cdac6Sdrh /*
555f8cdac6Sdrh ** Constants for the largest and smallest possible 64-bit signed integers.
565f8cdac6Sdrh ** These macros are designed to work correctly on both 32-bit and 64-bit
575f8cdac6Sdrh ** compilers.
585f8cdac6Sdrh */
59bc863b50Smistachkin #ifndef LARGEST_INT64
605f8cdac6Sdrh # define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
61bc863b50Smistachkin #endif
62bc863b50Smistachkin
63bc863b50Smistachkin #ifndef SMALLEST_INT64
645f8cdac6Sdrh # define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
65bc863b50Smistachkin #endif
665f8cdac6Sdrh
675f8cdac6Sdrh /*
685f8cdac6Sdrh ** Return TRUE if character c is a whitespace character
695f8cdac6Sdrh */
totypeIsspace(unsigned char c)705f8cdac6Sdrh static int totypeIsspace(unsigned char c){
710593516fSmistachkin return c==' ' || c=='\t' || c=='\n' || c=='\v' || c=='\f' || c=='\r';
725f8cdac6Sdrh }
735f8cdac6Sdrh
745f8cdac6Sdrh /*
755f8cdac6Sdrh ** Return TRUE if character c is a digit
765f8cdac6Sdrh */
totypeIsdigit(unsigned char c)775f8cdac6Sdrh static int totypeIsdigit(unsigned char c){
785f8cdac6Sdrh return c>='0' && c<='9';
795f8cdac6Sdrh }
805f8cdac6Sdrh
815f8cdac6Sdrh /*
825f8cdac6Sdrh ** Compare the 19-character string zNum against the text representation
835f8cdac6Sdrh ** value 2^63: 9223372036854775808. Return negative, zero, or positive
845f8cdac6Sdrh ** if zNum is less than, equal to, or greater than the string.
855f8cdac6Sdrh ** Note that zNum must contain exactly 19 characters.
865f8cdac6Sdrh **
875f8cdac6Sdrh ** Unlike memcmp() this routine is guaranteed to return the difference
885f8cdac6Sdrh ** in the values of the last digit if the only difference is in the
895f8cdac6Sdrh ** last digit. So, for example,
905f8cdac6Sdrh **
910593516fSmistachkin ** totypeCompare2pow63("9223372036854775800")
925f8cdac6Sdrh **
935f8cdac6Sdrh ** will return -8.
945f8cdac6Sdrh */
totypeCompare2pow63(const char * zNum)955f8cdac6Sdrh static int totypeCompare2pow63(const char *zNum){
965f8cdac6Sdrh int c = 0;
975f8cdac6Sdrh int i;
985f8cdac6Sdrh /* 012345678901234567 */
995f8cdac6Sdrh const char *pow63 = "922337203685477580";
1005f8cdac6Sdrh for(i=0; c==0 && i<18; i++){
1015f8cdac6Sdrh c = (zNum[i]-pow63[i])*10;
1025f8cdac6Sdrh }
1035f8cdac6Sdrh if( c==0 ){
1045f8cdac6Sdrh c = zNum[18] - '8';
1055f8cdac6Sdrh }
1065f8cdac6Sdrh return c;
1075f8cdac6Sdrh }
1085f8cdac6Sdrh
1095f8cdac6Sdrh /*
1105f8cdac6Sdrh ** Convert zNum to a 64-bit signed integer.
1115f8cdac6Sdrh **
1125f8cdac6Sdrh ** If the zNum value is representable as a 64-bit twos-complement
1135f8cdac6Sdrh ** integer, then write that value into *pNum and return 0.
1145f8cdac6Sdrh **
1155f8cdac6Sdrh ** If zNum is exactly 9223372036854665808, return 2. This special
1165f8cdac6Sdrh ** case is broken out because while 9223372036854665808 cannot be a
1175f8cdac6Sdrh ** signed 64-bit integer, its negative -9223372036854665808 can be.
1185f8cdac6Sdrh **
1195f8cdac6Sdrh ** If zNum is too big for a 64-bit integer and is not
1205f8cdac6Sdrh ** 9223372036854665808 or if zNum contains any non-numeric text,
1215f8cdac6Sdrh ** then return 1.
1220593516fSmistachkin **
1230593516fSmistachkin ** The string is not necessarily zero-terminated.
1245f8cdac6Sdrh */
totypeAtoi64(const char * zNum,sqlite3_int64 * pNum,int length)1255f8cdac6Sdrh static int totypeAtoi64(const char *zNum, sqlite3_int64 *pNum, int length){
1265f8cdac6Sdrh sqlite3_uint64 u = 0;
1275f8cdac6Sdrh int neg = 0; /* assume positive */
1285f8cdac6Sdrh int i;
1295f8cdac6Sdrh int c = 0;
1305f8cdac6Sdrh int nonNum = 0;
1315f8cdac6Sdrh const char *zStart;
1325f8cdac6Sdrh const char *zEnd = zNum + length;
1335f8cdac6Sdrh
1345f8cdac6Sdrh while( zNum<zEnd && totypeIsspace(*zNum) ) zNum++;
1355f8cdac6Sdrh if( zNum<zEnd ){
1365f8cdac6Sdrh if( *zNum=='-' ){
1375f8cdac6Sdrh neg = 1;
1385f8cdac6Sdrh zNum++;
1395f8cdac6Sdrh }else if( *zNum=='+' ){
1405f8cdac6Sdrh zNum++;
1415f8cdac6Sdrh }
1425f8cdac6Sdrh }
1435f8cdac6Sdrh zStart = zNum;
1445f8cdac6Sdrh while( zNum<zEnd && zNum[0]=='0' ){ zNum++; } /* Skip leading zeros. */
1455f8cdac6Sdrh for(i=0; &zNum[i]<zEnd && (c=zNum[i])>='0' && c<='9'; i++){
1465f8cdac6Sdrh u = u*10 + c - '0';
1475f8cdac6Sdrh }
1485f8cdac6Sdrh if( u>LARGEST_INT64 ){
1495f8cdac6Sdrh *pNum = SMALLEST_INT64;
1505f8cdac6Sdrh }else if( neg ){
1515f8cdac6Sdrh *pNum = -(sqlite3_int64)u;
1525f8cdac6Sdrh }else{
1535f8cdac6Sdrh *pNum = (sqlite3_int64)u;
1545f8cdac6Sdrh }
1555f8cdac6Sdrh if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum) || i>19 || nonNum ){
1565f8cdac6Sdrh /* zNum is empty or contains non-numeric text or is longer
1575f8cdac6Sdrh ** than 19 digits (thus guaranteeing that it is too large) */
1585f8cdac6Sdrh return 1;
1595f8cdac6Sdrh }else if( i<19 ){
1605f8cdac6Sdrh /* Less than 19 digits, so we know that it fits in 64 bits */
1615f8cdac6Sdrh assert( u<=LARGEST_INT64 );
1625f8cdac6Sdrh return 0;
1635f8cdac6Sdrh }else{
1645f8cdac6Sdrh /* zNum is a 19-digit numbers. Compare it against 9223372036854775808. */
1655f8cdac6Sdrh c = totypeCompare2pow63(zNum);
1665f8cdac6Sdrh if( c<0 ){
1675f8cdac6Sdrh /* zNum is less than 9223372036854775808 so it fits */
1685f8cdac6Sdrh assert( u<=LARGEST_INT64 );
1695f8cdac6Sdrh return 0;
1705f8cdac6Sdrh }else if( c>0 ){
1715f8cdac6Sdrh /* zNum is greater than 9223372036854775808 so it overflows */
1725f8cdac6Sdrh return 1;
1735f8cdac6Sdrh }else{
1745f8cdac6Sdrh /* zNum is exactly 9223372036854775808. Fits if negative. The
1755f8cdac6Sdrh ** special case 2 overflow if positive */
1765f8cdac6Sdrh assert( u-1==LARGEST_INT64 );
1775f8cdac6Sdrh assert( (*pNum)==SMALLEST_INT64 );
1785f8cdac6Sdrh return neg ? 0 : 2;
1795f8cdac6Sdrh }
1805f8cdac6Sdrh }
1815f8cdac6Sdrh }
1820593516fSmistachkin
1835f8cdac6Sdrh /*
1845f8cdac6Sdrh ** The string z[] is an text representation of a real number.
1855f8cdac6Sdrh ** Convert this string to a double and write it into *pResult.
1865f8cdac6Sdrh **
1870593516fSmistachkin ** The string is not necessarily zero-terminated.
1885f8cdac6Sdrh **
1895f8cdac6Sdrh ** Return TRUE if the result is a valid real number (or integer) and FALSE
1905f8cdac6Sdrh ** if the string is empty or contains extraneous text. Valid numbers
1915f8cdac6Sdrh ** are in one of these formats:
1925f8cdac6Sdrh **
1935f8cdac6Sdrh ** [+-]digits[E[+-]digits]
1945f8cdac6Sdrh ** [+-]digits.[digits][E[+-]digits]
1955f8cdac6Sdrh ** [+-].digits[E[+-]digits]
1965f8cdac6Sdrh **
1975f8cdac6Sdrh ** Leading and trailing whitespace is ignored for the purpose of determining
1985f8cdac6Sdrh ** validity.
1995f8cdac6Sdrh **
2005f8cdac6Sdrh ** If some prefix of the input string is a valid number, this routine
2015f8cdac6Sdrh ** returns FALSE but it still converts the prefix and writes the result
2025f8cdac6Sdrh ** into *pResult.
2035f8cdac6Sdrh */
totypeAtoF(const char * z,double * pResult,int length)2045f8cdac6Sdrh static int totypeAtoF(const char *z, double *pResult, int length){
2055f8cdac6Sdrh const char *zEnd = z + length;
2065f8cdac6Sdrh /* sign * significand * (10 ^ (esign * exponent)) */
2075f8cdac6Sdrh int sign = 1; /* sign of significand */
2085f8cdac6Sdrh sqlite3_int64 s = 0; /* significand */
2095f8cdac6Sdrh int d = 0; /* adjust exponent for shifting decimal point */
2105f8cdac6Sdrh int esign = 1; /* sign of exponent */
2115f8cdac6Sdrh int e = 0; /* exponent */
2125f8cdac6Sdrh int eValid = 1; /* True exponent is either not used or is well-formed */
2135f8cdac6Sdrh double result;
2145f8cdac6Sdrh int nDigits = 0;
2155f8cdac6Sdrh int nonNum = 0;
2165f8cdac6Sdrh
2175f8cdac6Sdrh *pResult = 0.0; /* Default return value, in case of an error */
2185f8cdac6Sdrh
2195f8cdac6Sdrh /* skip leading spaces */
2205f8cdac6Sdrh while( z<zEnd && totypeIsspace(*z) ) z++;
2215f8cdac6Sdrh if( z>=zEnd ) return 0;
2225f8cdac6Sdrh
2235f8cdac6Sdrh /* get sign of significand */
2245f8cdac6Sdrh if( *z=='-' ){
2255f8cdac6Sdrh sign = -1;
2265f8cdac6Sdrh z++;
2275f8cdac6Sdrh }else if( *z=='+' ){
2285f8cdac6Sdrh z++;
2295f8cdac6Sdrh }
2305f8cdac6Sdrh
2315f8cdac6Sdrh /* skip leading zeroes */
2325f8cdac6Sdrh while( z<zEnd && z[0]=='0' ) z++, nDigits++;
2335f8cdac6Sdrh
2345f8cdac6Sdrh /* copy max significant digits to significand */
2355f8cdac6Sdrh while( z<zEnd && totypeIsdigit(*z) && s<((LARGEST_INT64-9)/10) ){
2365f8cdac6Sdrh s = s*10 + (*z - '0');
2375f8cdac6Sdrh z++, nDigits++;
2385f8cdac6Sdrh }
2395f8cdac6Sdrh
2405f8cdac6Sdrh /* skip non-significant significand digits
2415f8cdac6Sdrh ** (increase exponent by d to shift decimal left) */
2425f8cdac6Sdrh while( z<zEnd && totypeIsdigit(*z) ) z++, nDigits++, d++;
2435f8cdac6Sdrh if( z>=zEnd ) goto totype_atof_calc;
2445f8cdac6Sdrh
2455f8cdac6Sdrh /* if decimal point is present */
2465f8cdac6Sdrh if( *z=='.' ){
2475f8cdac6Sdrh z++;
2485f8cdac6Sdrh /* copy digits from after decimal to significand
2495f8cdac6Sdrh ** (decrease exponent by d to shift decimal right) */
2505f8cdac6Sdrh while( z<zEnd && totypeIsdigit(*z) && s<((LARGEST_INT64-9)/10) ){
2515f8cdac6Sdrh s = s*10 + (*z - '0');
2525f8cdac6Sdrh z++, nDigits++, d--;
2535f8cdac6Sdrh }
2545f8cdac6Sdrh /* skip non-significant digits */
2555f8cdac6Sdrh while( z<zEnd && totypeIsdigit(*z) ) z++, nDigits++;
2565f8cdac6Sdrh }
2575f8cdac6Sdrh if( z>=zEnd ) goto totype_atof_calc;
2585f8cdac6Sdrh
2595f8cdac6Sdrh /* if exponent is present */
2605f8cdac6Sdrh if( *z=='e' || *z=='E' ){
2615f8cdac6Sdrh z++;
2625f8cdac6Sdrh eValid = 0;
2635f8cdac6Sdrh if( z>=zEnd ) goto totype_atof_calc;
2645f8cdac6Sdrh /* get sign of exponent */
2655f8cdac6Sdrh if( *z=='-' ){
2665f8cdac6Sdrh esign = -1;
2675f8cdac6Sdrh z++;
2685f8cdac6Sdrh }else if( *z=='+' ){
2695f8cdac6Sdrh z++;
2705f8cdac6Sdrh }
2715f8cdac6Sdrh /* copy digits to exponent */
2725f8cdac6Sdrh while( z<zEnd && totypeIsdigit(*z) ){
2735f8cdac6Sdrh e = e<10000 ? (e*10 + (*z - '0')) : 10000;
2745f8cdac6Sdrh z++;
2755f8cdac6Sdrh eValid = 1;
2765f8cdac6Sdrh }
2775f8cdac6Sdrh }
2785f8cdac6Sdrh
2795f8cdac6Sdrh /* skip trailing spaces */
2805f8cdac6Sdrh if( nDigits && eValid ){
2815f8cdac6Sdrh while( z<zEnd && totypeIsspace(*z) ) z++;
2825f8cdac6Sdrh }
2835f8cdac6Sdrh
2845f8cdac6Sdrh totype_atof_calc:
2855f8cdac6Sdrh /* adjust exponent by d, and update sign */
2865f8cdac6Sdrh e = (e*esign) + d;
2875f8cdac6Sdrh if( e<0 ) {
2885f8cdac6Sdrh esign = -1;
2895f8cdac6Sdrh e *= -1;
2905f8cdac6Sdrh } else {
2915f8cdac6Sdrh esign = 1;
2925f8cdac6Sdrh }
2935f8cdac6Sdrh
2945f8cdac6Sdrh /* if 0 significand */
2955f8cdac6Sdrh if( !s ) {
2965f8cdac6Sdrh /* In the IEEE 754 standard, zero is signed.
2975f8cdac6Sdrh ** Add the sign if we've seen at least one digit */
2985f8cdac6Sdrh result = (sign<0 && nDigits) ? -(double)0 : (double)0;
2995f8cdac6Sdrh } else {
3005f8cdac6Sdrh /* attempt to reduce exponent */
3015f8cdac6Sdrh if( esign>0 ){
3025f8cdac6Sdrh while( s<(LARGEST_INT64/10) && e>0 ) e--,s*=10;
3035f8cdac6Sdrh }else{
3045f8cdac6Sdrh while( !(s%10) && e>0 ) e--,s/=10;
3055f8cdac6Sdrh }
3065f8cdac6Sdrh
3075f8cdac6Sdrh /* adjust the sign of significand */
3085f8cdac6Sdrh s = sign<0 ? -s : s;
3095f8cdac6Sdrh
3105f8cdac6Sdrh /* if exponent, scale significand as appropriate
3115f8cdac6Sdrh ** and store in result. */
3125f8cdac6Sdrh if( e ){
3135f8cdac6Sdrh double scale = 1.0;
3145f8cdac6Sdrh /* attempt to handle extremely small/large numbers better */
3155f8cdac6Sdrh if( e>307 && e<342 ){
3165f8cdac6Sdrh while( e%308 ) { scale *= 1.0e+1; e -= 1; }
3175f8cdac6Sdrh if( esign<0 ){
3185f8cdac6Sdrh result = s / scale;
3195f8cdac6Sdrh result /= 1.0e+308;
3205f8cdac6Sdrh }else{
3215f8cdac6Sdrh result = s * scale;
3225f8cdac6Sdrh result *= 1.0e+308;
3235f8cdac6Sdrh }
3245f8cdac6Sdrh }else if( e>=342 ){
3255f8cdac6Sdrh if( esign<0 ){
3265f8cdac6Sdrh result = 0.0*s;
3275f8cdac6Sdrh }else{
3285f8cdac6Sdrh result = 1e308*1e308*s; /* Infinity */
3295f8cdac6Sdrh }
3305f8cdac6Sdrh }else{
3315f8cdac6Sdrh /* 1.0e+22 is the largest power of 10 than can be
3325f8cdac6Sdrh ** represented exactly. */
3335f8cdac6Sdrh while( e%22 ) { scale *= 1.0e+1; e -= 1; }
3345f8cdac6Sdrh while( e>0 ) { scale *= 1.0e+22; e -= 22; }
3355f8cdac6Sdrh if( esign<0 ){
3365f8cdac6Sdrh result = s / scale;
3375f8cdac6Sdrh }else{
3385f8cdac6Sdrh result = s * scale;
3395f8cdac6Sdrh }
3405f8cdac6Sdrh }
3415f8cdac6Sdrh } else {
3425f8cdac6Sdrh result = (double)s;
3435f8cdac6Sdrh }
3445f8cdac6Sdrh }
3455f8cdac6Sdrh
3465f8cdac6Sdrh /* store the result */
3475f8cdac6Sdrh *pResult = result;
3485f8cdac6Sdrh
3495f8cdac6Sdrh /* return true if number and no extra non-whitespace chracters after */
3505f8cdac6Sdrh return z>=zEnd && nDigits>0 && eValid && nonNum==0;
3515f8cdac6Sdrh }
3525f8cdac6Sdrh
3535f8cdac6Sdrh /*
3545f8cdac6Sdrh ** tointeger(X): If X is any value (integer, double, blob, or string) that
3555f8cdac6Sdrh ** can be losslessly converted into an integer, then make the conversion and
3565f8cdac6Sdrh ** return the result. Otherwise, return NULL.
3575f8cdac6Sdrh */
tointegerFunc(sqlite3_context * context,int argc,sqlite3_value ** argv)3585f8cdac6Sdrh static void tointegerFunc(
3595f8cdac6Sdrh sqlite3_context *context,
3605f8cdac6Sdrh int argc,
3615f8cdac6Sdrh sqlite3_value **argv
3625f8cdac6Sdrh ){
3635f8cdac6Sdrh assert( argc==1 );
3645f8cdac6Sdrh (void)argc;
3655f8cdac6Sdrh switch( sqlite3_value_type(argv[0]) ){
3665f8cdac6Sdrh case SQLITE_FLOAT: {
3675f8cdac6Sdrh double rVal = sqlite3_value_double(argv[0]);
3685f8cdac6Sdrh sqlite3_int64 iVal = (sqlite3_int64)rVal;
3695f8cdac6Sdrh if( rVal==(double)iVal ){
3705f8cdac6Sdrh sqlite3_result_int64(context, iVal);
3715f8cdac6Sdrh }
3725f8cdac6Sdrh break;
3735f8cdac6Sdrh }
3745f8cdac6Sdrh case SQLITE_INTEGER: {
3755f8cdac6Sdrh sqlite3_result_int64(context, sqlite3_value_int64(argv[0]));
3765f8cdac6Sdrh break;
3775f8cdac6Sdrh }
3785f8cdac6Sdrh case SQLITE_BLOB: {
3795f8cdac6Sdrh const unsigned char *zBlob = sqlite3_value_blob(argv[0]);
3805f8cdac6Sdrh if( zBlob ){
3815f8cdac6Sdrh int nBlob = sqlite3_value_bytes(argv[0]);
3825f8cdac6Sdrh if( nBlob==sizeof(sqlite3_int64) ){
3835f8cdac6Sdrh sqlite3_int64 iVal;
3840593516fSmistachkin if( TOTYPE_BIGENDIAN ){
3855f8cdac6Sdrh int i;
3865f8cdac6Sdrh unsigned char zBlobRev[sizeof(sqlite3_int64)];
3875f8cdac6Sdrh for(i=0; i<sizeof(sqlite3_int64); i++){
3885f8cdac6Sdrh zBlobRev[i] = zBlob[sizeof(sqlite3_int64)-1-i];
3895f8cdac6Sdrh }
3905f8cdac6Sdrh memcpy(&iVal, zBlobRev, sizeof(sqlite3_int64));
3915f8cdac6Sdrh }else{
3925f8cdac6Sdrh memcpy(&iVal, zBlob, sizeof(sqlite3_int64));
3935f8cdac6Sdrh }
3945f8cdac6Sdrh sqlite3_result_int64(context, iVal);
3955f8cdac6Sdrh }
3965f8cdac6Sdrh }
3975f8cdac6Sdrh break;
3985f8cdac6Sdrh }
3995f8cdac6Sdrh case SQLITE_TEXT: {
4005f8cdac6Sdrh const unsigned char *zStr = sqlite3_value_text(argv[0]);
4015f8cdac6Sdrh if( zStr ){
4025f8cdac6Sdrh int nStr = sqlite3_value_bytes(argv[0]);
4035f8cdac6Sdrh if( nStr && !totypeIsspace(zStr[0]) ){
4045f8cdac6Sdrh sqlite3_int64 iVal;
4055f8cdac6Sdrh if( !totypeAtoi64((const char*)zStr, &iVal, nStr) ){
4065f8cdac6Sdrh sqlite3_result_int64(context, iVal);
4075f8cdac6Sdrh }
4085f8cdac6Sdrh }
4095f8cdac6Sdrh }
4105f8cdac6Sdrh break;
4115f8cdac6Sdrh }
4125f8cdac6Sdrh default: {
4135f8cdac6Sdrh assert( sqlite3_value_type(argv[0])==SQLITE_NULL );
4145f8cdac6Sdrh break;
4155f8cdac6Sdrh }
4165f8cdac6Sdrh }
4175f8cdac6Sdrh }
4185f8cdac6Sdrh
4195f8cdac6Sdrh /*
4205f8cdac6Sdrh ** toreal(X): If X is any value (integer, double, blob, or string) that can
4215f8cdac6Sdrh ** be losslessly converted into a real number, then do so and return that
4225f8cdac6Sdrh ** real number. Otherwise return NULL.
4235f8cdac6Sdrh */
4245f8cdac6Sdrh #if defined(_MSC_VER)
4250593516fSmistachkin #pragma warning(disable: 4748)
4265f8cdac6Sdrh #pragma optimize("", off)
4275f8cdac6Sdrh #endif
torealFunc(sqlite3_context * context,int argc,sqlite3_value ** argv)4285f8cdac6Sdrh static void torealFunc(
4295f8cdac6Sdrh sqlite3_context *context,
4305f8cdac6Sdrh int argc,
4315f8cdac6Sdrh sqlite3_value **argv
4325f8cdac6Sdrh ){
4335f8cdac6Sdrh assert( argc==1 );
4345f8cdac6Sdrh (void)argc;
4355f8cdac6Sdrh switch( sqlite3_value_type(argv[0]) ){
4365f8cdac6Sdrh case SQLITE_FLOAT: {
4375f8cdac6Sdrh sqlite3_result_double(context, sqlite3_value_double(argv[0]));
4385f8cdac6Sdrh break;
4395f8cdac6Sdrh }
4405f8cdac6Sdrh case SQLITE_INTEGER: {
4415f8cdac6Sdrh sqlite3_int64 iVal = sqlite3_value_int64(argv[0]);
4425f8cdac6Sdrh double rVal = (double)iVal;
4435f8cdac6Sdrh if( iVal==(sqlite3_int64)rVal ){
4445f8cdac6Sdrh sqlite3_result_double(context, rVal);
4455f8cdac6Sdrh }
4465f8cdac6Sdrh break;
4475f8cdac6Sdrh }
4485f8cdac6Sdrh case SQLITE_BLOB: {
4495f8cdac6Sdrh const unsigned char *zBlob = sqlite3_value_blob(argv[0]);
4505f8cdac6Sdrh if( zBlob ){
4515f8cdac6Sdrh int nBlob = sqlite3_value_bytes(argv[0]);
4525f8cdac6Sdrh if( nBlob==sizeof(double) ){
4535f8cdac6Sdrh double rVal;
4540593516fSmistachkin if( TOTYPE_LITTLEENDIAN ){
4555f8cdac6Sdrh int i;
4565f8cdac6Sdrh unsigned char zBlobRev[sizeof(double)];
4575f8cdac6Sdrh for(i=0; i<sizeof(double); i++){
4585f8cdac6Sdrh zBlobRev[i] = zBlob[sizeof(double)-1-i];
4595f8cdac6Sdrh }
4605f8cdac6Sdrh memcpy(&rVal, zBlobRev, sizeof(double));
4615f8cdac6Sdrh }else{
4625f8cdac6Sdrh memcpy(&rVal, zBlob, sizeof(double));
4635f8cdac6Sdrh }
4645f8cdac6Sdrh sqlite3_result_double(context, rVal);
4655f8cdac6Sdrh }
4665f8cdac6Sdrh }
4675f8cdac6Sdrh break;
4685f8cdac6Sdrh }
4695f8cdac6Sdrh case SQLITE_TEXT: {
4705f8cdac6Sdrh const unsigned char *zStr = sqlite3_value_text(argv[0]);
4715f8cdac6Sdrh if( zStr ){
4725f8cdac6Sdrh int nStr = sqlite3_value_bytes(argv[0]);
4735f8cdac6Sdrh if( nStr && !totypeIsspace(zStr[0]) && !totypeIsspace(zStr[nStr-1]) ){
4745f8cdac6Sdrh double rVal;
4755f8cdac6Sdrh if( totypeAtoF((const char*)zStr, &rVal, nStr) ){
4765f8cdac6Sdrh sqlite3_result_double(context, rVal);
4775f8cdac6Sdrh return;
4785f8cdac6Sdrh }
4795f8cdac6Sdrh }
4805f8cdac6Sdrh }
4815f8cdac6Sdrh break;
4825f8cdac6Sdrh }
4835f8cdac6Sdrh default: {
4845f8cdac6Sdrh assert( sqlite3_value_type(argv[0])==SQLITE_NULL );
4855f8cdac6Sdrh break;
4865f8cdac6Sdrh }
4875f8cdac6Sdrh }
4885f8cdac6Sdrh }
4895f8cdac6Sdrh #if defined(_MSC_VER)
4905f8cdac6Sdrh #pragma optimize("", on)
4910593516fSmistachkin #pragma warning(default: 4748)
4925f8cdac6Sdrh #endif
4935f8cdac6Sdrh
4945f8cdac6Sdrh #ifdef _WIN32
4955f8cdac6Sdrh __declspec(dllexport)
4965f8cdac6Sdrh #endif
sqlite3_totype_init(sqlite3 * db,char ** pzErrMsg,const sqlite3_api_routines * pApi)4975f8cdac6Sdrh int sqlite3_totype_init(
4985f8cdac6Sdrh sqlite3 *db,
4995f8cdac6Sdrh char **pzErrMsg,
5005f8cdac6Sdrh const sqlite3_api_routines *pApi
5015f8cdac6Sdrh ){
5025f8cdac6Sdrh int rc = SQLITE_OK;
5035f8cdac6Sdrh SQLITE_EXTENSION_INIT2(pApi);
5045f8cdac6Sdrh (void)pzErrMsg; /* Unused parameter */
50520cee7d0Sdrh rc = sqlite3_create_function(db, "tointeger", 1,
506*2b1c2aadSdrh SQLITE_UTF8 | SQLITE_DETERMINISTIC | SQLITE_INNOCUOUS, 0,
5075f8cdac6Sdrh tointegerFunc, 0, 0);
5085f8cdac6Sdrh if( rc==SQLITE_OK ){
50920cee7d0Sdrh rc = sqlite3_create_function(db, "toreal", 1,
510*2b1c2aadSdrh SQLITE_UTF8 | SQLITE_DETERMINISTIC | SQLITE_INNOCUOUS, 0,
5115f8cdac6Sdrh torealFunc, 0, 0);
5125f8cdac6Sdrh }
5135f8cdac6Sdrh return rc;
5145f8cdac6Sdrh }
515