static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ int n = 0; double r; char *zBuf; assert( argc==1 || argc==2 ); if( argc==2 ){ if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return; n = sqlite3_value_int(argv[1]); if( n>30 ) n = 30; if( n<0 ) n = 0; } if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; r = sqlite3_value_double(argv[0]); /* If Y==0 and X will fit in a 64-bit int, ** handle the rounding directly, ** otherwise use printf. */ if( n==0 && r>=0 && r<LARGEST_INT64-1 ){ r = (double)((sqlite_int64)(r+0.5)); }else if( n==0 && r<0 && (-r)<LARGEST_INT64-1 ){ r = -(double)((sqlite_int64)((-r)+0.5)); }else{ zBuf = sqlite3_mprintf("%.*f",n,r); if( zBuf==0 ){ sqlite3_result_error_nomem(context); return; } sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8); sqlite3_free(zBuf); } sqlite3_result_double(context, r); }
/* ** Expression p should encode a floating point value between 1.0 and 0.0. ** Return 1024 times this value. Or return -1 if p is not a floating point ** value between 1.0 and 0.0. */ static int exprProbability(Expr *p){ double r = -1.0; if( p->op!=TK_FLOAT ) return -1; sqlite3AtoF(p->u.zToken, &r, sqlite3Strlen30(p->u.zToken), SQLITE_UTF8); assert( r>=0.0 ); if( r>1.0 ) return -1; return (int)(r*1000.0); }
/* ** Routines used to compute the standard deviation as an aggregate. */ static void stdDevStep(sqlite3_context *context, int argc, const char **argv){ StdDevCtx *p; double x; if( argc<1 ) return; p = sqlite3_aggregate_context(context, sizeof(*p)); if( p && argv[0] ){ x = sqlite3AtoF(argv[0], 0); p->sum += x; p->sum2 += x*x; p->cnt++; } }
/* ** Return the best representation of pMem that we can get into a ** double. If pMem is already a double or an integer, return its ** value. If it is a string or blob, try to convert it to a double. ** If it is a NULL, return 0.0. */ double sqlite3VdbeRealValue(Mem *pMem) { if( pMem->flags & MEM_Real ) { return pMem->r; } else if( pMem->flags & MEM_Int ) { return (double)pMem->i; } else if( pMem->flags & (MEM_Str|MEM_Blob) ) { if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8) || sqlite3VdbeMemNulTerminate(pMem) ) { return SQLITE_NOMEM; } assert( pMem->z ); return sqlite3AtoF(pMem->z, 0); } else { return 0.0; } }
/* ** Implementation of the round() function */ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv) { int n = 0; double r; char zBuf[500]; /* larger than the %f representation of the largest double */ assert( argc==1 || argc==2 ); if( argc==2 ) { if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return; n = sqlite3_value_int(argv[1]); if( n>30 ) n = 30; if( n<0 ) n = 0; } if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; r = sqlite3_value_double(argv[0]); sqlite3_snprintf(sizeof(zBuf),zBuf,"%.*f",n,r); sqlite3AtoF(zBuf, &r); sqlite3_result_double(context, r); }
/* ** Return the best representation of pMem that we can get into a ** double. If pMem is already a double or an integer, return its ** value. If it is a string or blob, try to convert it to a double. ** If it is a NULL, return 0.0. */ double sqlite3VdbeRealValue(Mem *pMem){ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); if( pMem->flags & MEM_Real ){ return pMem->r; }else if( pMem->flags & MEM_Int ){ return (double)pMem->u.i; }else if( pMem->flags & (MEM_Str|MEM_Blob) ){ /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ double val = (double)0; sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc); return val; }else{ /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ return (double)0; } }
/* ** Attempt to parse the given string into a julian day number. Return ** the number of errors. ** ** The following are acceptable forms for the input string: ** ** YYYY-MM-DD HH:MM:SS.FFF +/-HH:MM ** DDDD.DD ** now ** ** In the first form, the +/-HH:MM is always optional. The fractional ** seconds extension (the ".FFF") is optional. The seconds portion ** (":SS.FFF") is option. The year and date can be omitted as long ** as there is a time string. The time string can be omitted as long ** as there is a year and date. */ static int parseDateOrTime( sqlite3_context *context, const char *zDate, DateTime *p ){ double r; if( parseYyyyMmDd(zDate,p)==0 ){ return 0; }else if( parseHhMmSs(zDate, p)==0 ){ return 0; }else if( sqlite3StrICmp(zDate,"now")==0){ return setDateTimeToCurrent(context, p); }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){ p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5); p->validJD = 1; return 0; } return 1; }
/* ** Return the best representation of pMem that we can get into a ** double. If pMem is already a double or an integer, return its ** value. If it is a string or blob, try to convert it to a double. ** If it is a NULL, return 0.0. */ double sqlite3VdbeRealValue(Mem *pMem){ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); if( pMem->flags & MEM_Real ){ return pMem->r; }else if( pMem->flags & MEM_Int ){ return (double)pMem->u.i; }else if( pMem->flags & (MEM_Str|MEM_Blob) ){ double val = 0.0; pMem->flags |= MEM_Str; if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8) || sqlite3VdbeMemNulTerminate(pMem) ){ return 0.0; } assert( pMem->z ); sqlite3AtoF(pMem->z, &val); return val; }else{ return 0.0; } }
static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ int n = 0; double r; char *zBuf; assert( argc==1 || argc==2 ); if( argc==2 ){ if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return; n = sqlite3_value_int(argv[1]); if( n>30 ) n = 30; if( n<0 ) n = 0; } if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; r = sqlite3_value_double(argv[0]); zBuf = sqlite3_mprintf("%.*f",n,r); if( zBuf==0 ){ sqlite3_result_error_nomem(context); }else{ sqlite3AtoF(zBuf, &r); sqlite3_free(zBuf); sqlite3_result_double(context, r); } }
/* ** Return the best representation of pMem that we can get into a ** double. If pMem is already a double or an integer, return its ** value. If it is a string or blob, try to convert it to a double. ** If it is a NULL, return 0.0. */ double sqlite3VdbeRealValue(Mem *pMem){ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); if( pMem->flags & MEM_Real ){ return pMem->r; }else if( pMem->flags & MEM_Int ){ return (double)pMem->u.i; }else if( pMem->flags & (MEM_Str|MEM_Blob) ){ /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ double val = (double)0; pMem->flags |= MEM_Str; if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8) || sqlite3VdbeMemNulTerminate(pMem) ){ /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ return (double)0; } assert( pMem->z ); sqlite3AtoF(pMem->z, &val); return val; }else{ /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ return (double)0; } }
/* ** Process a modifier to a date-time stamp. The modifiers are ** as follows: ** ** NNN days ** NNN hours ** NNN minutes ** NNN.NNNN seconds ** NNN months ** NNN years ** start of month ** start of year ** start of week ** start of day ** weekday N ** unixepoch ** localtime ** utc ** ** Return 0 on success and 1 if there is any kind of error. If the error ** is in a system call (i.e. localtime()), then an error message is written ** to context pCtx. If the error is an unrecognized modifier, no error is ** written to pCtx. */ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ int rc = 1; int n; double r; char *z, zBuf[30]; z = zBuf; for(n=0; n<ArraySize(zBuf)-1 && zMod[n]; n++){ z[n] = (char)sqlite3UpperToLower[(u8)zMod[n]]; } z[n] = 0; switch( z[0] ){ #ifndef SQLITE_OMIT_LOCALTIME case 'l': { /* localtime ** ** Assuming the current time value is UTC (a.k.a. GMT), shift it to ** show local time. */ if( strcmp(z, "localtime")==0 ){ computeJD(p); p->iJD += localtimeOffset(p, pCtx, &rc); clearYMD_HMS_TZ(p); } break; } #endif case 'u': { /* ** unixepoch ** ** Treat the current value of p->iJD as the number of ** seconds since 1970. Convert to a real julian day number. */ if( strcmp(z, "unixepoch")==0 && p->validJD ){ p->iJD = (p->iJD + 43200)/86400 + 21086676*(i64)10000000; clearYMD_HMS_TZ(p); rc = 0; } #ifndef SQLITE_OMIT_LOCALTIME else if( strcmp(z, "utc")==0 ){ if( p->tzSet==0 ){ sqlite3_int64 c1; computeJD(p); c1 = localtimeOffset(p, pCtx, &rc); if( rc==SQLITE_OK ){ p->iJD -= c1; clearYMD_HMS_TZ(p); p->iJD += c1 - localtimeOffset(p, pCtx, &rc); } p->tzSet = 1; }else{ rc = SQLITE_OK; } } #endif break; } case 'w': { /* ** weekday N ** ** Move the date to the same time on the next occurrence of ** weekday N where 0==Sunday, 1==Monday, and so forth. If the ** date is already on the appropriate weekday, this is a no-op. */ if( strncmp(z, "weekday ", 8)==0 && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8) && (n=(int)r)==r && n>=0 && r<7 ){ sqlite3_int64 Z; computeYMD_HMS(p); p->validTZ = 0; p->validJD = 0; computeJD(p); Z = ((p->iJD + 129600000)/86400000) % 7; if( Z>n ) Z -= 7; p->iJD += (n - Z)*86400000; clearYMD_HMS_TZ(p); rc = 0; } break; } case 's': { /* ** start of TTTTT ** ** Move the date backwards to the beginning of the current day, ** or month or year. */ if( strncmp(z, "start of ", 9)!=0 ) break; z += 9; computeYMD(p); p->validHMS = 1; p->h = p->m = 0; p->s = 0.0; p->validTZ = 0; p->validJD = 0; if( strcmp(z,"month")==0 ){ p->D = 1; rc = 0; }else if( strcmp(z,"year")==0 ){ computeYMD(p); p->M = 1; p->D = 1; rc = 0; }else if( strcmp(z,"day")==0 ){ rc = 0; } break; } case '+': case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { double rRounder; for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){} if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){ rc = 1; break; } if( z[n]==':' ){ /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the ** specified number of hours, minutes, seconds, and fractional seconds ** to the time. The ".FFF" may be omitted. The ":SS.FFF" may be ** omitted. */ const char *z2 = z; DateTime tx; sqlite3_int64 day; if( !sqlite3Isdigit(*z2) ) z2++; memset(&tx, 0, sizeof(tx)); if( parseHhMmSs(z2, &tx) ) break; computeJD(&tx); tx.iJD -= 43200000; day = tx.iJD/86400000; tx.iJD -= day*86400000; if( z[0]=='-' ) tx.iJD = -tx.iJD; computeJD(p); clearYMD_HMS_TZ(p); p->iJD += tx.iJD; rc = 0; break; } z += n; while( sqlite3Isspace(*z) ) z++; n = sqlite3Strlen30(z); if( n>10 || n<3 ) break; if( z[n-1]=='s' ){ z[n-1] = 0; n--; } computeJD(p); rc = 0; rRounder = r<0 ? -0.5 : +0.5; if( n==3 && strcmp(z,"day")==0 ){ p->iJD += (sqlite3_int64)(r*86400000.0 + rRounder); }else if( n==4 && strcmp(z,"hour")==0 ){ p->iJD += (sqlite3_int64)(r*(86400000.0/24.0) + rRounder); }else if( n==6 && strcmp(z,"minute")==0 ){ p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0)) + rRounder); }else if( n==6 && strcmp(z,"second")==0 ){ p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0*60.0)) + rRounder); }else if( n==5 && strcmp(z,"month")==0 ){ int x, y; computeYMD_HMS(p); p->M += (int)r; x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12; p->Y += x; p->M -= x*12; p->validJD = 0; computeJD(p); y = (int)r; if( y!=r ){ p->iJD += (sqlite3_int64)((r - y)*30.0*86400000.0 + rRounder); } }else if( n==4 && strcmp(z,"year")==0 ){ int y = (int)r; computeYMD_HMS(p); p->Y += y; p->validJD = 0; computeJD(p); if( y!=r ){ p->iJD += (sqlite3_int64)((r - y)*365.0*86400000.0 + rRounder); } }else{ rc = 1; } clearYMD_HMS_TZ(p); break; } default: { break; } } return rc; }